﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;

namespace System.Windows
{
    public static partial class UIElementExtension
    {
        public static Rect InvisibleBounds = new Rect(-1000000, 0, 0, 0);
        public static bool GetVisible(this UIElement element)
        {
            return element.Visibility == Visibility.Visible;
        }
        public static void SetVisible(this UIElement element, bool visible)
        {
            Visibility newVisibiliity = visible ? Visibility.Visible : Visibility.Collapsed;
            if (newVisibiliity != element.Visibility)
            {
                element.Visibility = newVisibiliity;
                INotifyVisibilityChanged notifyVisibilityChanged = element as INotifyVisibilityChanged;
                if (notifyVisibilityChanged != null)
                    notifyVisibilityChanged.OnVisibilityChanged();
            }
        }
        public static Size GetDesiredSize(this UIElement element)
        {
            return element.DesiredSize;
        }
        public static double GetRoundedSize(double size)
        {
            return Math.Ceiling(size);
        }
        public static Size GetRoundedSize(Size size)
        {
            return new Size(Math.Ceiling(size.Width), Math.Ceiling(size.Height));
        }
        public static FrameworkElement GetRootVisual(this UIElement element)
        {
            if (!BrowserInteropHelper.IsBrowserHosted)
            {
                PresentationSource presentationSource = PresentationSource.FromVisual(element);
                return presentationSource != null ? presentationSource.RootVisual as FrameworkElement : null;
            }
            else
                return (FrameworkElement)Application.Current.MainWindow.Content;
        }
        public static Point MapPoint(this UIElement element, Point p, UIElement destination)
        {
            if (destination != null)
                return element.TranslatePoint(p, destination);
            else
                if (!BrowserInteropHelper.IsBrowserHosted)
                    return element.PointToScreen(p);
                else
                    return element.TranslatePoint(p, element.GetRootVisual());
        }
        public static Point MapPointFromScreen(this UIElement element, Point p)
        {
            if (!BrowserInteropHelper.IsBrowserHosted)
                return element.PointFromScreen(p);
            else
                return element.GetRootVisual().MapPoint(p, element);
        }
        public static Rect MapRect(this UIElement element, Rect rect, UIElement destination)
        {
            return new Rect(element.MapPoint(rect.TopLeft(), destination), element.MapPoint(rect.BottomRight(), destination));
        }
        public static Rect MapRectFromScreen(this UIElement element, Rect rect)
        {
            return new Rect(element.MapPointFromScreen(rect.TopLeft()), element.MapPointFromScreen(rect.BottomRight()));
        }
        public static bool HasDefaultRenderTransform(this UIElement element)
        {
            return element.RenderTransform == null ||
                element.RenderTransform is MatrixTransform && ((MatrixTransform)element.RenderTransform).Matrix.IsIdentity;
        }
        public static bool Focus(this UIElement element)
        {
            if (element is Control)
                return (element as Control).Focus();
            return false;
        }
        public static void InvalidateParentsOfModifiedChildren(this UIElement element)
        {
            bool needsRemeasuring = false;
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var child = VisualTreeHelper.GetChild(element, i) as UIElement;
                if (child != null)
                {
                    InvalidateParentsOfModifiedChildren(child);
                    if (!child.IsMeasureValid)
                        needsRemeasuring = true;
                }
            }
            if (needsRemeasuring)
                element.InvalidateMeasure();
        }
    }
}
